﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ClusteringWrraper
{
    public class FriendsList : Dictionary<string,FacebookUser>
    {
        public double Grade;
        public int NumOfIter;
        public FriendsMatrix Matrix;
        public LinkedList<FriendsList> SubLists;
        public FriendsList LonelyFriends;
        private readonly double _prec = 0.0001;
        public int UserUID;//Can be a random number if this is a sub list.
        public string Name;

        public FriendsList(double prec)
        {
            _prec = prec;
            UserUID = new Random().Next(0, 1000000);
            Name = "";
        }

        public FriendsList(double prec, int userUid)
        {
            _prec = prec;
            UserUID = userUid;
            Name = "";
        }

        public void AddUser(FacebookUser user)
        {
            Add(user.Uid, user);
        }

        public FacebookUser GetUserByUID(string uid)
        {
            if (ContainsKey(uid))
                return this[uid];
            return null;
        }

        private void FillMatrix()
        {
            Matrix = new FriendsMatrix(this.Count, UserUID);
            LonelyFriends = new FriendsList(_prec);
            foreach (var user in this.Values)
            {
                if (user.MutualFriendsUidToUser.Count > 0)
                {
                    Matrix.AddFbUserToMatrix(user);
                }
                else
                {
                    LonelyFriends.AddUser(user);
                }
            }
            Matrix.UpdateMatrix();
        }

        public void ClusterList()
        {
            double deltaQ;
            int numOfGroups;
            FillMatrix();
            var ts = Matrix.RunAlgo(_prec);
            SubLists = Matrix.ParseAlgoOutput(ts, out deltaQ, out numOfGroups);
        }

        public new String ToString()
        {
            var sb = new StringBuilder(String.Format("\ngrade = {0}, numOfIter = {1}:\r\n", Grade, NumOfIter));
            foreach (var s in this)
            {
                sb.Append(s.Value.Name + ",");
            }
            return sb.ToString();
        }

        private const string PostRestUrl = "stream.publish?message={0}&target_id={1}&";

        public void PostToGroupWallsWithRestApi(string token, string msg)
        {
            foreach (var user in Values)
            {
                QueryHelper.GetResAsync(String.Format(PostRestUrl,msg,user.Uid),
                    token,null,(data, res) => res = res);
            }
        }
        
        public void PostToGroupWallsWithGraphApi(string token,string msg)
        {
            var parameters = new LinkedList<KeyValuePair<string, string>>();
            parameters.AddLast(new KeyValuePair<string, string>("message", msg));

            var privacy = new StringBuilder("{\"value\":\"CUSTOM\",\"friends\":\"SOME_FRIENDS\",\"allow\":");
            bool first = true;
            foreach (var facebookUser in Values)
            {
                privacy.AppendFormat("{0}\"{1}\"",first ? "":",",facebookUser.Uid);
                first = false;
            }
            privacy.Append("}");

            parameters.AddLast(new KeyValuePair<string, string>("privacy", privacy.ToString()));

            QueryHelper.HttpPost(token, "https://graph.facebook.com/me/feed", parameters);

        }
    }
}
